package com.hsgene.dict.controller;

import com.hsgene.common.exception.CommonErrorCode;
import com.hsgene.common.util.basic.SimpleStringUtils;
import com.hsgene.common.util.exception.ErrorCode;
import com.hsgene.common.util.resolver.FromSession;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.support.LimitHelper;
import com.hsgene.common.util.support.Pagination;
import com.hsgene.common.util.web.session.UserInfo;
import com.hsgene.dict.condition.SysDictCondition;
import com.hsgene.dict.domain.SysDict;
import com.hsgene.dict.dto.SysDictDto;
import com.hsgene.dict.dto.SysDictIdsDto;
import com.hsgene.dict.exception.DictErrorCode;
import com.hsgene.dict.service.DictService;
import com.hsgene.dict.service.api.GeneratorService;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @desc:字典
 * @author: fuxiang
 * @date: 2018/9/25 15:23
 */
@RestController
@RequestMapping("/v1.0/genetic/testing/dict")
public class DictController {
    private Logger logger = LogManager.getLogger(DictController.class);

    @Autowired
    private DictService dictService;

    @Autowired
    private GeneratorService generatorService;

    /**
     * @param condition 查询条件
     * @param page      页数
     * @param size      每页数量
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.support.Pagination<com.hsgene.dict.dto
     * .SysDictDto>>
     * @description 字典列表/查询字典列表
     * @author maodi
     * @createDate 2018/11/29 10:28
     */
    @GetMapping
    public ApiResult<Pagination<SysDictDto>> sysDicts(SysDictCondition condition, Integer page, Integer size) {
        try {
            if (page == null) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NULL);
            }
            if (size == null) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NULL);
            }
            if (!SimpleStringUtils.isPositiveInteger(page.toString())) {
                return ApiResult.fail(CommonErrorCode.PAGE_IS_NOT_POSITIVE_INTEGER);
            }
            if (!SimpleStringUtils.isPositiveInteger(size.toString())) {
                return ApiResult.fail(CommonErrorCode.SIZE_IS_NOT_POSITIVE_INTEGER);
            }
            LimitHelper limitHelper = LimitHelper.create(page, size, true);
            condition.setLimitHelper(limitHelper);
            List<SysDictDto> sysDictDtos = dictService.queryDicts(condition);
            int count = (page - 1) * size + 1;
            for (SysDictDto dto : sysDictDtos) {
                dto.setNumber(count++);
            }
            int totalCount = dictService.queryDictCount(condition);
            Pagination pagination = Pagination.newInstance(limitHelper, totalCount, sysDictDtos);
            return ApiResult.succ(pagination);
        } catch (Exception e) {
            logger.error(DictErrorCode.QUERY_DICT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.QUERY_DICT_IS_ERROR);
        }
    }

    /**
     * @param id 字典逻辑主键id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.dict.dto.SysDictDto>
     * @description 根据id获取字典信息
     * @author maodi
     * @createDate 2018/11/29 10:38
     */
    @GetMapping("{id}")
    public ApiResult<SysDictDto> sysDict(@PathVariable("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return ApiResult.fail(DictErrorCode.SYS_DICT_ID_IS_NOT_NULL);
            }
            return ApiResult.succ(dictService.select(id));
        } catch (Exception e) {
            logger.error(DictErrorCode.SELECT_BY_ID_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.SELECT_BY_ID_IS_ERROR);
        }
    }

    /**
     * @param idsStr 字典逻辑主键id数组字符串，以英文逗号分隔
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.dict.dto.SysDictDto>
     * @description 根据id获取字典信息
     * @author fuxiang
     * @createDate 2018/11/29 10:38
     */
    @GetMapping("select/ids")
    public ApiResult<List<SysDictDto>> sysDicts(@RequestParam("ids") String idsStr) {
        if (StringUtils.isBlank(idsStr)) {
            return ApiResult.fail(DictErrorCode.SYS_DICT_IDS_IS_NOT_NULL);
        }
        String[] ids = StringUtils.split(idsStr, ",");
        if (ids == null || ids.length < 1) {
            return ApiResult.fail(DictErrorCode.SYS_DICT_IDS_IS_NOT_NULL);
        }
        return dictService.selectIds(ids);
    }

    /**
     * @param sysDict  字典
     * @param userInfo 用户信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 新增字典数据
     * @author maodi
     * @createDate 2018/11/29 14:41
     */
    @PostMapping
    public ApiResult<NullObject> insert(@RequestBody SysDict sysDict, @FromSession UserInfo userInfo) {
        try {
            ErrorCode code = checkSysDict(sysDict, userInfo, true);
            if (code != null) {
                return ApiResult.fail(code);
            }
            String type = sysDict.getType();
            String dictNameId = sysDict.getLabel();
            String label = sysDict.getValue();
            int count = dictService.queryCountByValue(null, type, dictNameId, label);
            if (count > 0) {
                return ApiResult.fail(DictErrorCode.DICT_IS_EXIST);
            }
            dictService.insert(sysDict);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.INSERT_DICT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.INSERT_DICT_IS_ERROR);
        }
    }

    /**
     * @param sysDict  字典
     * @param userInfo 用户信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 修改字典信息
     * @author maodi
     * @createDate 2018/11/29 14:55
     */
    @PutMapping
    public ApiResult<NullObject> update(@RequestBody SysDict sysDict, @FromSession UserInfo userInfo) {
        try {
            ErrorCode code = checkSysDict(sysDict, userInfo, false);
            if (code != null) {
                return ApiResult.fail(code);
            }
            String id = sysDict.getId();
            String type = sysDict.getType();
            String dictNameId = sysDict.getLabel();
            String label = sysDict.getValue();
            int count = dictService.queryCountByValue(id, type, dictNameId, label);
            if (count > 0) {
                return ApiResult.fail(DictErrorCode.DICT_IS_EXIST);
            }
            int existCount = dictService.queryCountById(id);
            if (existCount < 1) {
                return ApiResult.fail(DictErrorCode.DICT_IS_NOT_EXIST);
            }
            dictService.update(sysDict);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.UPDATE_DICT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.UPDATE_DICT_IS_ERROR);
        }
    }

    /**
     * @param id 字典逻辑主键id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 删除字典
     * @author maodi
     * @createDate 2018/11/29 15:10
     */
    @DeleteMapping("{id}")
    public ApiResult<NullObject> delete(@PathVariable("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return ApiResult.fail(DictErrorCode.DICT_ID_IS_NOT_NULL);
            }
            int count = dictService.queryCountById(id);
            if (count < 1) {
                return ApiResult.fail(DictErrorCode.DICT_HAS_BEEN_DELETED);
            }
            dictService.delete(id);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.DELETE_DICT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.DELETE_DICT_IS_ERROR);
        }
    }

    /**
     * @param sysDictIdsDto 字典id数组字符串信息
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 批量删除字典
     * @author maodi
     * @createDate 2018/11/29 15:20
     */
    @DeleteMapping
    public ApiResult<NullObject> deleteMulti(@RequestBody SysDictIdsDto sysDictIdsDto) {
        try {
            if (sysDictIdsDto == null) {
                return ApiResult.fail(DictErrorCode.DICT_IDS_IS_NOT_NULL);
            }
            String idsStr = sysDictIdsDto.getIds();
            if (StringUtils.isBlank(idsStr)) {
                return ApiResult.fail(DictErrorCode.DICT_IDS_IS_NOT_NULL);
            }
            String[] ids = idsStr.split(",");
            dictService.deleteMulti(ids);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.MULTI_DELETE_DICT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.MULTI_DELETE_DICT_IS_ERROR);
        }
    }

    /**
     * @param id 字典逻辑主键id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 增加一次字典使用数量
     * @author maodi
     * @createDate 2018/11/29 15:27
     */
    @PutMapping("add/{id}")
    public ApiResult<NullObject> usedCountAdd(@PathVariable("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return ApiResult.fail(DictErrorCode.DICT_ID_IS_NOT_NULL);
            }
            int count = dictService.queryCountById(id);
            if (count < 1) {
                return ApiResult.fail(DictErrorCode.DICT_HAS_BEEN_DELETED);
            }
            dictService.addDictUsedCount(id);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.DICT_USED_COUNT_ADD_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.DICT_USED_COUNT_ADD_IS_ERROR);
        }
    }

    /**
     * @param id 字典逻辑主键id
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 减少一次字典使用数量
     * @author maodi
     * @createDate 2018/11/29 15:30
     */
    @PutMapping("reduce/{id}")
    public ApiResult<NullObject> usedCountReduce(@PathVariable("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return ApiResult.fail(DictErrorCode.DICT_ID_IS_NOT_NULL);
            }
            int count = dictService.queryCountById(id);
            if (count < 1) {
                return ApiResult.fail(DictErrorCode.DICT_HAS_BEEN_DELETED);
            }
            int usedCount = dictService.queryDictUsedCountById(id);
            if (usedCount > 0) {
                dictService.reduceDictUsedCount(id);
            }
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.DICT_USED_COUNT_REDUCE_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.DICT_USED_COUNT_REDUCE_IS_ERROR);
        }
    }

    /**
     * @param idsStr id数组字符串
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 批量增加一次字典使用数量
     * @author maodi
     * @createDate 2018/12/26 10:39
     */
    @PutMapping("addMulti")
    public ApiResult<NullObject> usedCountAddMulti(@RequestParam("ids") String idsStr) {
        try {
            if (StringUtils.isBlank(idsStr)) {
                return ApiResult.fail(DictErrorCode.SYS_DICT_IDS_IS_NOT_NULL);
            }
            String[] ids = idsStr.split(",");
            dictService.addMultiDictUsedCount(ids);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.ADD_MULTI_USED_COUNT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.ADD_MULTI_USED_COUNT_IS_ERROR);
        }
    }

    /**
     * @param idsStr id数组字符串
     * @return com.hsgene.common.util.result.ApiResult<com.hsgene.common.util.result.NullObject>
     * @description 批量减少一次字典使用数量
     * @author maodi
     * @createDate 2018/12/26 10:39
     */
    @PutMapping("reduceMulti")
    public ApiResult<NullObject> usedCountReduceMulti(@RequestParam("ids") String idsStr) {
        try {
            if (StringUtils.isBlank(idsStr)) {
                return ApiResult.fail(DictErrorCode.SYS_DICT_IDS_IS_NOT_NULL);
            }
            String[] ids = idsStr.split(",");
            dictService.reduceMultiDictUsedCount(ids);
            return ApiResult.succ();
        } catch (Exception e) {
            logger.error(DictErrorCode.REDUCE_MULTI_USED_COUNT_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.REDUCE_MULTI_USED_COUNT_IS_ERROR);
        }
    }

    /**
     * @param
     * @return com.hsgene.common.util.result.ApiResult<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
     * @description 获取所有分类下拉框数据源
     * @author maodi
     * @createDate 2018/11/28 14:53
     */
    @GetMapping("select/classifies")
    public ApiResult<List<Map<String, Object>>> classifies() {
        try {
            return ApiResult.succ(dictService.queryAllClassifies());
        } catch (Exception e) {
            logger.error(DictErrorCode.SELECT_ALL_CLASSIFIES_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.SELECT_ALL_CLASSIFIES_IS_ERROR);
        }
    }

    /**
     * @param classifyId 字典分类id
     * @return com.hsgene.common.util.result.ApiResult<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
     * @description 根据字典分类id获取字典名称下拉框数据源
     * @author maodi
     * @createDate 2018/12/3 15:15
     */
    @GetMapping("select/labels")
    public ApiResult<List<Map<String, Object>>> labels(@RequestParam("classify_id") String classifyId) {
        try {
            return ApiResult.succ(dictService.queryLabelsByClassifyId(classifyId));
        } catch (Exception e) {
            logger.error(DictErrorCode.QUERY_LABELS_BY_CLASSIFY_ID_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.QUERY_LABELS_BY_CLASSIFY_ID_IS_ERROR);
        }
    }

    /**
     * @param id sys_dict_addtion表的id
     * @return com.hsgene.common.util.result.ApiResult<java.util.List<java.util.Map<java.lang.String,java.lang.Object>>>
     * @description 根据字典名称id获取上级节点
     * @author maodi
     * @createDate 2018/11/28 14:53
     */
    @GetMapping("select/values/{id}")
    public ApiResult<List<Map<String, Object>>> queryValuesByLabel(@PathVariable("id") String id) {
        try {
            if (StringUtils.isBlank(id)) {
                return ApiResult.fail(DictErrorCode.SYS_DICT_ADDTION_ID_IS_NOT_NULL);
            }
            return ApiResult.succ(dictService.queryValuesByLabel(id));
        } catch (Exception e) {
            logger.error(DictErrorCode.SYS_DICTS_BY_SYS_DICT_ADDTION_ID_IS_ERROR.getMessage(), e);
            return ApiResult.fail(DictErrorCode.SYS_DICTS_BY_SYS_DICT_ADDTION_ID_IS_ERROR);
        }
    }

    /**
     * @param sysDict  字典信息
     * @param userInfo 用户信息
     * @return com.hsgene.common.util.exception.ErrorCode
     * @description 校验字典信息
     * @author maodi
     * @createDate 2018/11/29 13:50
     */
    private ErrorCode checkSysDict(SysDict sysDict, UserInfo userInfo, Boolean isInsert) {
        if (sysDict == null) {
            return DictErrorCode.DICT_INFO_IS_NOT_NULL;
        }
        String type = sysDict.getType();
        if (StringUtils.isBlank(type)) {
            return DictErrorCode.DICT_TYPE_IS_NOT_NULL;
        }
        String label = sysDict.getLabel();
        if (StringUtils.isBlank(label)) {
            return DictErrorCode.DICT_LABEL_IS_NOT_NULL;
        }
        String value = sysDict.getValue();
        if (StringUtils.isBlank(value)) {
            return DictErrorCode.DICT_VALUE_IS_NOT_NULL;
        }
        if (userInfo == null) {
            return CommonErrorCode.USER_INFO_IS_NULL;
        }
        String userId = userInfo.getUserId();
        if (StringUtils.isBlank(userId)) {
            return CommonErrorCode.USER_ID_IS_NULL;
        }
        Date date = new Date();
        sysDict.setUpdateBy(userId);
        sysDict.setUpdateDate(date);
        String id = sysDict.getId();
        if (isInsert) {
            sysDict.setCreateBy(userId);
            sysDict.setCreateDate(date);
            sysDict.setId(generatorService.getGenerator("", "").getData().getSerialNumber());
        } else {
            if (StringUtils.isBlank(id)) {
                return DictErrorCode.DICT_ID_IS_NOT_NULL;
            }
        }
        return null;
    }

    /***
     * 根据字典名称查询所有字典
     * @author jcl
     * @date 2018/12/4 15:58
     * @param dictAddtionId 字典名称的id
     * @return
     */
    @GetMapping("select/value/{dict_addtion_id}")
    public ApiResult valueByDictAddtionId(@PathVariable(name = "dict_addtion_id") String dictAddtionId) {
        try {
            return dictService.valueByDictAddtionId(dictAddtionId);
        } catch (Exception e) {
            logger.error("query dict value by lable error", e);
            return new ApiResult<>(500, "failed", "query dict value by lable error", e.toString());
        }
    }
}
